package com.atguigu.srb.core.service.impl;

import com.atguigu.common.exception.Assert;
import com.atguigu.common.result.ResponseEnum;
import com.atguigu.common.utils.MD5;
import com.atguigu.srb.base.utils.JwtUtils;
import com.atguigu.srb.core.mapper.UserAccountMapper;
import com.atguigu.srb.core.mapper.UserInfoMapper;
import com.atguigu.srb.core.mapper.UserLoginRecordMapper;
import com.atguigu.srb.core.pojo.entity.UserAccount;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.pojo.entity.UserLoginRecord;
import com.atguigu.srb.core.pojo.query.UserInfoQuery;
import com.atguigu.srb.core.pojo.vo.LoginVO;
import com.atguigu.srb.core.pojo.vo.RegisterVO;
import com.atguigu.srb.core.pojo.vo.UserInfoVO;
import com.atguigu.srb.core.service.UserInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Objects;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 用户基本信息 服务实现类
 * </p>
 *
 * @author lupengning
 * @since 2021-05-27
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements
    UserInfoService {

  @Resource
  private UserAccountMapper userAccountMapper;

  @Resource
  private UserLoginRecordMapper userLoginRecordMapper;

  @Transactional(rollbackFor = {Exception.class})
  @Override
  public void register(RegisterVO registerVO) {
    //判断用户是否已经注册
    LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
    Integer count = baseMapper
        .selectCount(queryWrapper.eq(UserInfo::getMobile, registerVO.getMobile()));
    Assert.isTrue(count == 0, ResponseEnum.MOBILE_EXIST_ERROR);
    //插入用户基本信息
    UserInfo userInfo = UserInfo.builder().userType(registerVO.getUserType())
        .nickName(registerVO.getMobile())
        .name(registerVO.getMobile())
        .mobile(registerVO.getMobile())
        .password(MD5.encrypt(registerVO.getPassword()))
        .status(UserInfo.STATUS_NORMAL)
        .headImg(
            "https://gulimall-lpn.oss-cn-shenzhen.aliyuncs.com/%E8%B5%B5%E9%87%91%E9%BA%A6.jpg")
        .build();
    baseMapper.insert(userInfo);
    //创建会员账户
    UserAccount userAccount = new UserAccount();
    userAccount.setUserId(userInfo.getId());
    userAccountMapper.insert(userAccount);
  }

  @Transactional(rollbackFor = {Exception.class})
  @Override
  public UserInfoVO login(LoginVO loginVO, String ip) {
    String mobile = loginVO.getMobile();
    String password = loginVO.getPassword();
    Integer userType = loginVO.getUserType();
    //获取会员
    LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
    UserInfo userInfo = baseMapper.selectOne(
        queryWrapper.eq(UserInfo::getMobile, mobile).eq(UserInfo::getUserType, userType));

    // 用户不存在
    Assert.notNull(userInfo, ResponseEnum.LOGIN_MOBILE_ERROR);
    // 密码不正确
    Assert.equals(MD5.encrypt(password), userInfo.getPassword(), ResponseEnum.LOGIN_PASSWORD_ERROR);
    // 用户是否被禁用
    Assert.equals(userInfo.getStatus(), UserInfo.STATUS_NORMAL, ResponseEnum.LOGIN_LOKED_ERROR);

    //记录登录日志
    UserLoginRecord loginRecord = new UserLoginRecord();
    loginRecord.setUserId(userInfo.getId());
    loginRecord.setIp(ip);
    userLoginRecordMapper.insert(loginRecord);

    //生产token
    String token = JwtUtils.createToken(userInfo.getId(), userInfo.getName());
    UserInfoVO userInfoVO = UserInfoVO.builder().token(token)
        .name(userInfo.getName())
        .nickName(userInfo.getNickName())
        .headImg(userInfo.getHeadImg())
        .mobile(userInfo.getMobile())
        .userType(userType)
        .build();

    return userInfoVO;
  }

  @Override
  public IPage<UserInfo> listPage(Page<UserInfo> pageParam, UserInfoQuery userInfoQuery) {

    if (Objects.isNull(userInfoQuery)) {
      return baseMapper.selectPage(pageParam, null);
    }

    String mobile = userInfoQuery.getMobile();
    Integer status = userInfoQuery.getStatus();
    Integer userType = userInfoQuery.getUserType();

    LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();

    return baseMapper.selectPage(pageParam,
        queryWrapper.eq(StringUtils.isNotBlank(mobile), UserInfo::getMobile, mobile)
            .eq(!Objects.isNull(status), UserInfo::getStatus, status)
            .eq(!Objects.isNull(userType), UserInfo::getUserType, userType)
    );
  }

  @Transactional(rollbackFor = {Exception.class})
  @Override
  public void lock(Long id, Integer status) {

    UserInfo userInfo = UserInfo.builder().id(id)
        .status(status).build();
    baseMapper.updateById(userInfo);
  }

  @Override
  public boolean isRegisterMobile(String mobile) {
    LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
    Integer count = baseMapper.selectCount(queryWrapper.eq(UserInfo::getMobile, mobile));
    return count > 0;
  }
}
